/*
 * Copyright 2018 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.codegen.utils;

import com.lap.codegen.domain.Column;
import com.lap.codegen.utils.CodeEnum.JavaType;
import com.lap.codegen.utils.CodeEnum.YN;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * <pre>
 * 生成校验信息
 * </pre>
 *
 * @author 劳水生
 * @version 1.0.0
 */
public final class AnnotationUtils {
    private static final String NOT_EMPTY = "@NotEmpty(message = \"{%s}\")";
    private static final String NOT_NULL = "@NotNull(message = \"{%s}\")";
    private static final String NOT_NULL_PK = "@NotNull(message = \"{%s}\", groups = { Update.class })";
    private static final String LENGTH = "@Length(max = %s, message = \"{%s}\")";
    private static final String DATE = "@DateTimeFormat(pattern = \"%s\")";
    private static final String API_MODEL = "@ApiModelProperty(value = \"%s\", example = \"%s\", dataType = \"%s\")";

    private AnnotationUtils() {
    }

    /**
     * <pre>
     * 创建数据模型注解代码
     * </pre>
     *
     * @param tableName 表名
     * @param column    列名
     */
    public static String annotation(String tableName, Column column) {
        StringBuilder content = new StringBuilder();
        List<String> dataList = new LinkedList<>();
        column.setAnnotation(dataList);

        String val = String.format(API_MODEL, column.getComment(), getExample(column), column.getJavaType());
        dataList.add(val);

        content.append(getMust(tableName, column));
        content.append(getLength(tableName, column));
        // 时间类型
        String type = column.getJavaType();
        if (JavaType.DATE.getValue().equals(type)) {
            // @JsonFormat
            String dbType = column.getDbType();
            if ("date".equalsIgnoreCase(dbType)) {
                dataList.add(String.format(DATE, "yyyy-MM-dd"));
            } else {
                dataList.add(String.format(DATE, "yyyy-MM-dd HH:mm:ss"));
            }
        }
        return content.toString();
    }

    /**
     * <pre>
     * 注解非空
     * </pre>
     *
     * @param tableName 表名
     * @param column    列名
     * @param msg       信息
     * @return
     */
    private static String getValAnnotation(String tableName, Column column, String msg) {
        StringBuilder sb = new StringBuilder();
        sb.append(tableName);
        sb.append(".");
        sb.append(column.getLowerName());
        sb.append(".");
        sb.append(msg);// "notEmpty.message"
        return sb.toString();
    }

    /**
     * <pre>
     * 解析例子
     * </pre>
     *
     * @param column 列名
     * @return
     */
    private static String getExample(Column column) {
        String type = column.getJavaType();
        if (JavaType.DATE.getValue().equals(type)) {
            String dbType = column.getDbType();
            if ("date".equalsIgnoreCase(dbType)) {
                return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            } else {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            }
        } else if (JavaType.INT.getValue().equals(type)) {
            return "1";
        } else if (JavaType.LONG.getValue().equals(type)) {
            return "1000";
        } else if (JavaType.DOUBLE.getValue().equals(type)) {
            return "1.00";
        } else {
            return "测试";
        }
    }

    /**
     * <pre>
     * 非空字符串
     * </pre>
     *
     * @param column
     * @param key
     * @param msg
     * @return
     */
    private static String getNotNullMsg(Column column, String key, String msg) {
        StringBuilder sb = new StringBuilder();
        sb.append(key);
        sb.append("=");
        sb.append(column.getComment());
        sb.append(msg);// 不能为空
        return sb.toString();
    }

    /**
     * <pre>
     * 生成字符串长度
     * </pre>
     *
     * @param tableName 表名
     * @param column    列名
     * @return 返回错误提示
     */
    private static String getLength(String tableName, Column column) {
        String type = column.getJavaType();
        String length = column.getLength();
        StringBuilder result = new StringBuilder();
        if (StringUtils.isNotBlank(length) && JavaType.STRING.getValue().equals(type)) {
            String annotation = getValAnnotation(tableName, column, "maxLength.message");
            column.getAnnotation().add(String.format(LENGTH, length, annotation));

            String content = getLengthMsg(column, annotation, "长度不能超过 ");
            result.append(content).append(".\n");
        }
        return result.toString();
    }

    /**
     * <pre>
     * 长度
     * </pre>
     *
     * @param column 列名
     * @param key    key
     * @param msg    提示信息
     * @return
     */
    private static String getLengthMsg(Column column, String key, String msg) {
        StringBuilder sb = new StringBuilder();
        sb.append(key);
        sb.append("=");
        sb.append(column.getComment());
        sb.append(msg);
        sb.append("{max}");
        return sb.toString();
    }

    /**
     * <pre>
     * 生成必填注解，同时生成必填文件
     * </pre>
     *
     * @param tableName 表名
     * @param column    列名
     * @return
     */
    private static String getMust(String tableName, Column column) {
        String must = column.getMust();
        String type = column.getJavaType();
        String key = column.getKey();
        StringBuilder result = new StringBuilder();
        if (Objects.nonNull(must) && YN.NO.getValue().equals(must)) {
            if (JavaType.STRING.getValue().equals(type)) {
                String annotation = getValAnnotation(tableName, column, "notEmpty.message");
                column.getAnnotation().add(String.format(NOT_EMPTY, annotation));

                String content = getNotNullMsg(column, annotation, "不能为空.");
                result.append(content).append("\n");
            } else {
                String annotation = getValAnnotation(tableName, column, "notNull.message");
                if ("PRI".equals(key)) {
                    column.getAnnotation().add(String.format(NOT_NULL_PK, annotation));
                } else {
                    column.getAnnotation().add(String.format(NOT_NULL, annotation));
                }
                String content = getNotNullMsg(column, annotation, "不能为空.");
                result.append(content).append("\n");
            }
        }
        return result.toString();
    }

}
